library ieee;
use ieee.std_logic_1164.all;

use ieee.numeric_std.all;
use work.Achtung_const.all;

--								|--------------|
--	Y	clk		 --------|					|------ command
--	O	rst		 --------|					|------ data_in	S
--	U	row		 --------|					|------ data_out	R
--	R	column	 --------|	THIS ENT		|------ address	A
--		pixel_in	 --------|					|------ byte		M
--	P	pixel_out	------|					|------ done
--	A	complete	 --------|					|
--	R							|--------------|
--	T
entity address_translator is 
	port(
	
		clk 		:in std_logic;
		rst 		:in std_logic;
		
		row 		:in unsigned(9 downto 0);
		column 		:in unsigned(9 downto 0);
	
		command  	:out std_logic_vector(1 downto 0);
		data_in		:in SRAM_Data;
		data_out 	:out SRAM_Data;
		address 	:out SRAM_Address;
		byte		:out std_logic;
		done		:in std_logic;
		
		get_pixel	:in std_logic;
		set_pixel	:in std_logic;
		
		pixel_in 	: in std_logic_vector(1 downto 0);
		pixel_out 	: out std_logic_vector(1 downto 0);
		
		complete 	:out std_logic
	);
end entity;	
	
	
	architecture rtl of address_translator is
	
	type state is (IDLE, SET_PX, GET_PX);
	signal next_state, current_state: state;
	signal data_buffer: std_logic_vector(15 downto 0);
	signal adr : std_logic_vector(19 downto 0);
	begin
	
	
	
	
	
	process (clk, rst, done, row, column)
begin

	if(rst = '0') then
		current_state <= IDLE;
	else
		if (rising_edge(clk)) then
		current_state <= next_state;
		end if;
		
		byte <= column(0);
		adr <= std_logic_vector((row * 320) + (column srl 1));
		case current_state is
			when IDLE =>
								command <= "00";
								complete <= '0';
								if(set_pixel = '1' and get_pixel = '0') then
									next_state <= SET_PX;
								elsif (get_pixel = '1' and set_pixel = '0') then
									next_state <= GET_PX;
								else 
									next_state <= IDLE;
								end if;
			when GET_PX =>
								command <= "01";
								address <= adr(17 downto 0);
								if (done = '1') then
									complete <= '1';
									if((column(0)) = '1') then
										pixel_out <= data_in(1 downto 0);
									else
										pixel_out <= data_in(9 downto 8);
									end if;
										
										if(set_pixel = '1' and get_pixel = '0') then
									next_state <= SET_PX;
								elsif (get_pixel = '1' and set_pixel = '0') then
									next_state <= GET_PX;
								else 
									next_state <= IDLE;
								end if;
								else
									complete <= '0';
								end if;
			when SET_PX =>
								command <= "10";								
								if((column(0)) = '1') then
									data_out <= "00000000000000" & pixel_in;
								else
									data_out <= "000000" & pixel_in & "00000000";
								end if;
								address <=  adr(17 downto 0);
								if done = '1' then
									complete <= '1';
									if(set_pixel = '1' and get_pixel = '0') then
									next_state <= SET_PX;
								elsif (get_pixel = '1' and set_pixel = '0') then
									next_state <= GET_PX;
								else 
									next_state <= IDLE;
								end if;
								else 
									complete <= '0';
								end if;
			end case;
	end if;

end process;
	

end rtl;